import 'dart:developer';

import 'package:im_base/im_base.dart';
import 'package:im_base/public/global/im_keys.dart';
import 'package:tencent_im_sdk_plugin/enum/V2TimSDKListener.dart';
import 'package:tencent_im_sdk_plugin/enum/friend_type_enum.dart';
import 'package:tencent_im_sdk_plugin/enum/log_level_enum.dart';
import 'package:tencent_im_sdk_plugin/manager/v2_tim_manager.dart';
import 'package:tencent_im_sdk_plugin/models/v2_tim_callback.dart';
import 'package:tencent_im_sdk_plugin/models/v2_tim_conversation.dart';
import 'package:tencent_im_sdk_plugin/models/v2_tim_friend_info.dart';
import 'package:tencent_im_sdk_plugin/models/v2_tim_friend_info_result.dart';
import 'package:tencent_im_sdk_plugin/models/v2_tim_friend_operation_result.dart';
import 'package:tencent_im_sdk_plugin/models/v2_tim_group_info.dart';
import 'package:tencent_im_sdk_plugin/models/v2_tim_message.dart';
import 'package:tencent_im_sdk_plugin/models/v2_tim_value_callback.dart';
import 'package:tencent_im_sdk_plugin/tencent_im_sdk_plugin.dart';
import '../ext/string_ext.dart';

///为了降低 各组件的Controller之间的耦合度,采用单例模式进行IM的相关操作
class TimService {
  ///常用的常量值
  ///当前用户是否已被拉黑 'true' 'false'
  static const IS_BLACK = 'isBlack';

  V2TIMManager? v2timManager;

  factory TimService() => _getInstance();

  static TimService get instance => _getInstance();
  static TimService? _instance;

  static TimService _getInstance() {
    if (_instance == null) {
      _instance = TimService._internal();
    }
    return _instance!;
  }

  TimService._internal() {
    if (v2timManager == null) {
      v2timManager = TencentImSDKPlugin.v2TIMManager;
    }
    v2timManager!.initSDK(
        sdkAppID: 1400149528,
        loglevel: LogLevelEnum.V2TIM_LOG_DEBUG,
        listener: V2TimSDKListener(
            onKickedOffline: () => writeIMData(IMKeys.kickOut, true),
            onUserSigExpired: () => writeIMData(IMKeys.kickOut, true)));
  }

  void joinGroup(String groupId, {Function(V2TimCallback)? callback}) async {
    await v2timManager!
        .joinGroup(groupID: groupId, message: '加入群聊')
        .then((value) {
      callback?.call(value);
    });
  }

  Future<V2TimValueCallback<String>> createGroup(String groupName,
      {String? intro, String? faceUrl}) async {
    return await v2timManager!
        .createGroup(groupType: 'public', groupName: groupName);
  }

  ///根据会话标记已读
  void markMessageRead(V2TimConversation conversation) async {
    log('markMessageRead------------------');
    if (!conversation.groupID.isNullEmpty()) {
      markMessageReadById(conversation.groupID!, true);
    } else {
      markMessageReadById(conversation.userID!, false);
    }
  }

  ///根据id标记会话已读
  void markMessageReadById(String id, bool isGroup) async {
    log('markMessageReadById---$id');
    if (isGroup) {
      v2timManager!
          .getMessageManager()
          .markGroupMessageAsRead(groupID: id)
          .then((value) {
        log("markMessageRead$value");
      });
    } else {
      v2timManager!
          .getMessageManager()
          .markC2CMessageAsRead(userID: id)
          .then((value) {
        log("markMessageRead${value.code}---${value.desc}");
      });
    }
  }

  ///发送文字消息
  void sendTextMessage(String content,
      {required String id,
      required bool isGroup,
      Function(V2TimValueCallback<V2TimMessage>)? callBack}) async {
    if (id.isNullEmpty()) {
      showToast("账号信息有误");
      return;
    }
    await v2timManager!.v2TIMMessageManager
        .createTextMessage(text: content)
        .then((value) {
      v2timManager!.v2TIMMessageManager
          .sendMessage(
              id: value.data?.id ?? '',
              receiver: isGroup ? '' : id,
              groupID: isGroup ? id : '')
          .then((value) {
        callBack?.call(value);
        onSendMessage(value);
      });
    });
  }

  ///发送图片消息
  void sendImageMessage(String path, String id, bool isGroup,
      {Function(V2TimValueCallback<V2TimMessage>)? callBack}) async {
    var result = await v2timManager!.v2TIMMessageManager
        .createImageMessage(imagePath: path);

    await v2timManager!.v2TIMMessageManager
        .sendMessage(
            id: result.data?.id ?? '',
            receiver: isGroup ? "" : id,
            groupID: isGroup ? id : "")
        .then((value) {
      callBack?.call(value);
      onSendMessage(value);
    });
  }

  ///发送视频消息
  void sendVideoMessage(String path, String id, bool isGroup, int duration,
      String type, String snapshotPath,
      {Function(V2TimValueCallback<V2TimMessage>)? callBack}) async {
    var result = await v2timManager!.v2TIMMessageManager.createVideoMessage(
        videoFilePath: path,
        type: type,
        duration: duration,
        snapshotPath: snapshotPath);
    await v2timManager!.v2TIMMessageManager
        .sendMessage(
            id: result.data?.id ?? '',
            receiver: isGroup ? "" : id,
            groupID: isGroup ? id : "")
        .then((value) {
      callBack?.call(value);
      onSendMessage(value);
    });
  }

  ///发送语音消息
  void sendAudioMessage(String path, int timeLength, String id, bool isGroup,
      {Function(V2TimValueCallback<V2TimMessage>)? callBack}) async {
    var result = await v2timManager!.v2TIMMessageManager
        .createSoundMessage(soundPath: path, duration: timeLength);
    await v2timManager!.v2TIMMessageManager
        .sendMessage(
            id: result.data?.id ?? '',
            receiver: isGroup ? '' : id,
            groupID: isGroup ? id : '')
        .then((value) {
      callBack?.call(value);
      onSendMessage(value);
    });
  }

  ///将发送消息的事件抛出
  void onSendMessage(V2TimValueCallback<V2TimMessage> value) {
    writeIMData(IMKeys.SEND_MESSAGE, value.code == 0);
  }

  ///删除消息
  void deleteMessage(String msgId, {Function(V2TimCallback)? callBack}) async {
    await v2timManager!
        .getMessageManager()
        .deleteMessageFromLocalStorage(msgID: msgId)
        .then((value) {
      if (callBack != null) callBack(value);
    });
  }

  ///撤回消息
  void withDrawMessage(String msgId,
      {Function(V2TimCallback)? callBack}) async {
    await v2timManager!
        .getMessageManager()
        .revokeMessage(msgID: msgId)
        .then((value) => callBack?.call(value));
  }

  ///获取我的群列表
  Future<List<V2TimGroupInfo>?> getMyGroups() async {
    var result = await v2timManager!.v2TIMGroupManager.getJoinedGroupList();
    if (result.code == 0) {
      return result.data;
    }
    return List.empty();
  }

  ///黑名单列表
  Future<List<V2TimFriendInfo>> getBlackList() async {
    var result = await v2timManager!.v2TIMFriendshipManager.getBlackList();
    log('getBlackList---${result.code}---${result.data}');
    if (result.code == 0) {
      return result.data ?? List.empty();
    } else {
      showToast(result.desc);
    }
    return List.empty();
  }

  ///添加到黑名单
  Future<V2TimFriendOperationResult?> addToBlackList(String id) async {
    var setResult = await setFriendInfo(id, customInfo: {IS_BLACK: 'true'});
    log('addToBlackList---${setResult.code}--${setResult.desc}');
    var result = await v2timManager!.v2TIMFriendshipManager
        .addToBlackList(userIDList: [id]);
    log('addToBlackList---${result.code}---${result.desc}');
    if (result.code == 0) {
      showToast('已将该用户加入黑名单');
      return result.data?.first;
    } else {
      showToast(result.desc);
    }
    return null;
  }

  ///将用户移出黑名单
  Future<V2TimFriendOperationResult?> deleteFromBlackList(String id) async {
    var result = await v2timManager!.v2TIMFriendshipManager
        .deleteFromBlackList(userIDList: [id]);
    log('addToBlackList---${result.code}---${result.desc}');
    if (result.code == 0) {
      showToast('已将该用户移出黑名单');
      var infoResult = await setFriendInfo(id, customInfo: {IS_BLACK: 'false'});
      log('deleteFromBlackList---${infoResult.code}---${infoResult.desc}');
      return result.data?.first;
    } else {
      showToast(result.desc);
    }
    return null;
  }

  ///设置用户信息
  Future<V2TimCallback> setFriendInfo(String userID,
      {String? remark, Map<String, String>? customInfo}) async {
    return await v2timManager!.v2TIMFriendshipManager.setFriendInfo(
        userID: userID, friendRemark: remark, friendCustomInfo: customInfo);
  }

  ///获取用户信息
  Future<V2TimFriendInfoResult?> getFriendInfo(String userId) async {
    var result = await v2timManager!.v2TIMFriendshipManager
        .getFriendsInfo(userIDList: [userId]);
    if (result.code == 0) {
      return result.data?.first;
    }
    return null;
  }

  ///添加好友
  Future<V2TimValueCallback<V2TimFriendOperationResult>> addFriend(
      String userId) async {
    return await v2timManager!.v2TIMFriendshipManager.addFriend(
        userID: userId, addType: FriendTypeEnum.V2TIM_FRIEND_TYPE_BOTH);
  }

  ///置顶会话
  ///这里传入的是对方用户id,所以做一个拼接
  Future<V2TimCallback> pinConversation(String conID, bool isPinned) async {
    log('pinConversation----$isPinned');
    return await v2timManager!.v2ConversationManager
        .pinConversation(conversationID: 'c2c_$conID', isPinned: isPinned);
  }
}
